﻿using Abp;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Collections.Extensions;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.Runtime.Caching;
using Abp.Runtime.Session;
using Abp.Runtime.Validation;
using Microsoft.AspNetCore.Mvc;
using Mt.Site.Application.ContentManagement.Dto;
using Mt.Site.Application.ContentManagement.FrontEnd.Dto;
using Mt.Site.Application.Dto;
using Mt.Site.Core.Base.Authorization;
using Mt.Site.Core.ContentManagement;
using Mt.Site.Core.ContentManagement.Entities;
using Mt.Site.Core.ContentManagement.Permissions;
using Mt.Site.Core.ContentManagement.Preview;
using Mt.Site.Core.ContentManagement.Values;
using Mt.Site.Core.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace Mt.Site.Application.ContentManagement
{
    public class Content2AppService : MtSiteAppServiceBase, IContent2AppService
    {
        private readonly IContent2Manager _contentManager;

        private readonly IFileObjectManager _fileObjectManager;
        private readonly IPermissionManager _permissionManager;
        private readonly IPreviewDataManager _previewDataManager;

        private readonly ICacheManager _cacheManager;

        public Content2AppService(
            IContent2Manager contentManager,
            IFileObjectManager fileObjectManager,
            IPermissionManager permissionManager,
            IPreviewDataManager previewDataManager,
            ICacheManager cacheManager)
        {
            _contentManager = contentManager;
            _fileObjectManager = fileObjectManager;
            _permissionManager = permissionManager;
            _previewDataManager = previewDataManager;
            _cacheManager = cacheManager;
        }

        [AbpAuthorize]
        public async Task ResetListApiCacheAsync()
        {
            await _cacheManager.GetCache<string, PagedResultDto<_ContentListDto>>(ApiCacheNames.Content2PagedList).ClearAsync();
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Create, ContentPermissions.Pages_Manage_Content_Update, RequireAllPermissions = false)]
        public async Task<Guid> CreateOrUpdateAsync(CreateOrUpdateInput2 input)
        {
            Guid id;
            if (input.Id.HasValue)
            {
                id = await _contentManager.UpdateAsync(input.Values, input.Id.Value, input.MenuId, input.CustomKey, input.RelateId);

                //if (MtSiteConsts2.BackgroundJobs)
                //{
                //    _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
                //        new BaseAndMenuIdArgs
                //        {
                //            FromLanguage = AbpSession.CultureName(),
                //            FromTenantId = AbpSession.GetTenantId(),
                //            Id = id,
                //            MenuId = input.MenuId,
                //            OperateType = OptionType.Update
                //        });
                //}
                return id;
            }
            else
            {
                id = await _contentManager.CreateAsync(input.Values, input.MenuId, input.CustomKey, input.RelateId);

                IList<Guid> fileIds = null;
                if (input.RandomId.HasValue)
                {
                    fileIds = await _fileObjectManager.BuildRelationships(id, input.RandomId.Value);
                }


                //if (MtSiteConsts2.BackgroundJobs)
                //{
                //    _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
                //    new BaseAndMenuIdArgs
                //    {
                //        FromLanguage = AbpSession.CultureName(),
                //        FromTenantId = AbpSession.GetTenantId(),
                //        Id = id,
                //        MenuId = input.MenuId,
                //        OperateType = OptionType.Create
                //    });

                //    if (fileIds != null)
                //    {
                //        foreach (var item in fileIds)
                //        {
                //            _backgroundJobManager.Enqueue<SynchorizationFileObjectJob, BaseAndMenuIdArgs>(
                //                        new BaseAndMenuIdArgs
                //                        {
                //                            FromLanguage = AbpSession.CultureName(),
                //                            FromTenantId = AbpSession.GetTenantId(),
                //                            Id = item,
                //                            OperateType = OptionType.Create
                //                        }, BackgroundJobPriority.BelowNormal);
                //        }
                //    }
                //}
                return id;
            }
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Delete)]
        public async Task DeleteAysnc(DeleteInput2 input)
        {
            await _contentManager.DeleteAysnc(input.Id, input.MenuId, input.RelateId);

            //if (item != null && MtSiteConsts2.BackgroundJobs)
            //{
            //    _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
            //        new BaseAndMenuIdArgs
            //        {
            //            FromLanguage = AbpSession.CultureName(),
            //            FromTenantId = AbpSession.GetTenantId(),
            //            Id = item.Id,
            //            MenuId = item.MenuId,
            //            OperateType = OptionType.Delete
            //        });
            //}
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Delete)]
        public async Task DeleteListAysnc(EntityIdListWithMenuIdDto input)
        {
            await _contentManager.DeleteListAysnc(input.List, input.MenuId, input.RelateId);

            //if (MtSiteConsts2.BackgroundJobs)
            //{
            //    foreach (var item in itemList)
            //    {
            //        _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
            //            new BaseAndMenuIdArgs
            //            {
            //                FromLanguage = AbpSession.CultureName(),
            //                FromTenantId = AbpSession.GetTenantId(),
            //                Id = item.Id,
            //                MenuId = item.MenuId,
            //                OperateType = OptionType.Delete
            //            });
            //    }
            //}
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content)]
        public async Task<ContentConfig> GetConfigAsync(GetConfigInput input)
        {
            return await _contentManager.GetConfig(input.CustomKey, input.MenuId);
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content)]
        public async Task<ConfigAndPermisions> GetConfigAndPermisionsAsync(GetConfigInput input)
        {
            var config = await _contentManager.GetConfig(input.CustomKey, input.MenuId);

            var permissions = _permissionManager.GetCustomMenuPermissions(ContentPermissionProvider.ModuleName2);
            var list = new Dictionary<string, bool>();
            var userId = AbpSession.GetUserId();
            foreach (var p in permissions)
            {
                list.Add(p.Name, PermissionChecker.IsGranted(userId, p, input.MenuId));
            }
            return new ConfigAndPermisions
            {
                Config = config,
                Permissions = list
            };
        }

        [HttpPost]
        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Create, 
            ContentPermissions.Pages_Manage_Content_Update, RequireAllPermissions = false)]
        public async Task<Dictionary<string, object>> GetContentForEditAsync(GetContent2ForEditInput input)
        {
            return await _contentManager.GetContentForEdit(input.Id, input.MenuId, input.CustomKey, input.RelateId);
        }

        [HttpPost]
        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Query)]
        public async Task<PagedContent<Dictionary<string, object>>> GetContentListByPagedAsync(PagedContent2Input input)
        {
            input.CustomKey = await _contentManager.GetCustomKey(input.CustomKey, input.MenuId);

            Func<IQueryable<Content2>, IQueryable<Content2>> func = (q) =>
            {
                //if (input.RelateId.HasValue) {
                //    return q.Where(t=> t.RelateId == input.RelateId && t.Key == input.CustomKey)
                //        .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter))
                //        .WhereIf(input.InfoState == MtSiteConsts2.Values.ActiveState, t => t.IsActive == true)
                //        .WhereIf(input.InfoState == MtSiteConsts2.Values.UnActiveState, t => t.IsActive == false);
                //}
                //else
                //{
                    return q.WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter))
                        .WhereIf(input.InfoState == MtSiteConsts2.Values.ActiveState, t => t.IsActive == true)
                        .WhereIf(input.InfoState == MtSiteConsts2.Values.UnActiveState, t => t.IsActive == false);
                //}
            };

            return await _contentManager.GetContentListByPagedAsync(func, input.SkipCount, input.MaxResultCount, input.CustomKey, input.MenuId, input.RelateId);
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Update)]
        public async Task SetNewOrderNumberAsync(NewSortNumberWithMenuIdInput input)
        {
            await _contentManager.SetNewOrderNumberAsync(input.Id, input.MenuId, input.NewNumber, input.RelateId);
            //if (item != null && MtSiteConsts2.BackgroundJobs)
            //{
            //    _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
            //        new BaseAndMenuIdArgs
            //        {
            //            FromLanguage = AbpSession.CultureName(),
            //            FromTenantId = AbpSession.GetTenantId(),
            //            Id = item.Id,
            //            MenuId = item.MenuId,
            //            OperateType = OptionType.Update
            //        });
            //}
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Publish)]
        public async Task SetStatusAsync(SetStatusWithMenuIdInput input)
        {
            await _contentManager.SetStatus(input.IdList, input.MenuId, input.IsActive);

            //if (MtSiteConsts2.BackgroundJobs)
            //{
            //    foreach (var item in itemList)
            //    {
            //        _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
            //            new BaseAndMenuIdArgs
            //            {
            //                FromLanguage = AbpSession.CultureName(),
            //                FromTenantId = AbpSession.GetTenantId(),
            //                Id = item.Id,
            //                MenuId = item.MenuId,
            //                OperateType = OptionType.Update
            //            });
            //    }
            //}
        }


        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Update)]
        public async Task SwapObjectSortAsync(SwapSortNumberWithMenuIdInput input)
        {
            var idList = input.IdOrderList.Select(c => c.Id).ToList();
            var orderList = input.IdOrderList.Select(c => c.Order).ToList();

            if (idList.Count == 0)
            {
                return;
            }

            await _contentManager.SwapObjectSortAsync(idList, input.MenuId, orderList, input.RelateId);

            //if (MtSiteConsts2.BackgroundJobs)
            //{
            //    foreach (var item in itemList)
            //    {
            //        _backgroundJobManager.Enqueue<SynchorizationContentJob, BaseAndMenuIdArgs>(
            //            new BaseAndMenuIdArgs
            //            {
            //                FromLanguage = AbpSession.CultureName(),
            //                FromTenantId = AbpSession.GetTenantId(),
            //                Id = item.Id,
            //                MenuId = item.MenuId,
            //                OperateType = OptionType.Update
            //            });
            //    }
            //}
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Query)]
        public async Task CopyToOtherMenuAsync(ToAnotherMenuInput input)
        {
            if ( !PermissionChecker.IsGranted(ContentPermissions.Pages_Manage_Content_Create, input.ToMenuId))
            {
                throw new AbpValidationException(L("MenuOperationPermissionsMustBeGranted", input.ToMenuId, "Create"));
            }
            await _contentManager.CopyToOtherMenuAsync(input.Id, input.FromMenuId, input.FromRelateId, input.ToMenuId, input.ToRelateId);
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Delete)]
        public async Task MoveToAnotherMenuAsync(ToAnotherMenuInput input)
        {
            if (!PermissionChecker.IsGranted(ContentPermissions.Pages_Manage_Content_Create, input.ToMenuId))
            {
                throw new AbpValidationException(L("MenuOperationPermissionsMustBeGranted", input.ToMenuId, "Create"));
            }
            await _contentManager.MoveToAnotherMenuAsync(input.Id, input.FromMenuId, input.FromRelateId, input.ToMenuId, input.ToRelateId);
        }

        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Query)]
        public async Task ShareToOtherMenuAsync(ToOtherMenusInput input)
        {
            foreach (var item in input.ToMenus)
            {
                await _contentManager.ShareToOtherMenuAsync(input.Id, input.FromMenuId, input.FromRelateId, item.MenuId, item.RelateId, input.ManagementType);
            }
        }

        [HttpPost]
        [AbpAuthorize(ContentPermissions.Pages_Manage_Content_Query)]
        public async Task<SharedInfoOutput> GetSharedInfoAsync(GetSharedInfoInput input)
        {
            //1 . 被分享的： 来源于栏目  新闻动态 / 工作动态
            //2.  源数据：   分享链接 至   
            //                         新闻动态 / 工作动态
            //                         新闻动态 / 基层动态

            return await _contentManager.GetSharedInfoAsync(input.Id, input.MenuId, input.RelateId);
        }

        [HttpPost]
        [AbpAuthorize]
        public async Task<AllMenusForOperation> GetMenusForOperationAsync(GetMenusForOperationInput input)
        {
            if (input.Id.HasValue)
            {
                return await _contentManager.GetAllMenusForOperationAsync(input.CustomKey, input.Id.Value, input.OperationType, input.MenuId);
            }

            return await _contentManager.GetAllMenusAsync(input.CustomKey);
        }

        [HttpPost]
        [AbpAuthorize]
        public async Task<AllMenusForOperation> GetAllMenusForTopicOperationAsync(GetAllMenusForTopicOperationInput input)
        {
            return await _contentManager.GetAllMenusForTopicOperationAsync(input.CustomKey, input.CustomKey2);
        }

        #region 回收站
        ///// <summary>
        ///// 获取软删除的数据
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //[AbpAuthorize(ContentPermissions.Pages_Manage_Content_Query)]
        //public async Task<PagedResultDto<PagedContentSoftDelInput>> GetContentListSoftDelAsync(PagedContentInput input)
        //{
        //    using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
        //    {
        //        var query = _contentRepository.GetAll()
        //                    .Where(t => t.IsDeleted)
        //                    .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter) || t.Body.Contains(input.Filter))
        //                    .OrderByDescending(t => t.DeletionTime);
        //        var pageCount = query.Count();
        //        var List = await query.PageBy(input).ToListAsync();
        //        return new PagedResultDto<PagedContentSoftDelInput>(pageCount, ObjectMapper.Map<List<PagedContentSoftDelInput>>(List));
        //    }
        //}



        ///// <summary>
        ///// 撤销删除数据
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //[AbpAuthorize(ContentPermissions.Pages_Manage_Content_Update)]
        //public async Task RecoverContentAsync(EntityIdListDto input)
        //{
        //    await _contentManager.RecoverContentAsync(input.List);
        //}
        #endregion
    }
}
